﻿package com.moonshineproject.plugin {
	import __AS3__.vec.Vector;
	
	import com.moonshineproject.GlobalEventDispatcher;
	import com.moonshineproject.plugin.console.ConsoleOutputEvent;
	import com.moonshineproject.plugin.console.MarkupTextLineModel;
	import com.moonshineproject.plugin.console.view.ConsoleModeEvent;
	import com.moonshineproject.text.TextLineModel;
	import com.moonshineproject.utils.HtmlFormatter;
	
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	import no.doomsday.console.ConsoleUtil;
	
	public class PluginBase implements IPlugin 
	{
		protected namespace console;
		
		public function get name():String			{ return "Plugin Base"; }
		public function get author():String			{ return "N/A"; }
		public function get description():String	{ return "A plugin base that plugins can extend to gain easier access to some functionality."; }
		
		/**
		 * ensures if the plugin will be activated by default when the plugin 
		 * is loaded for the first time (without settings xml file written)
		 * */
		public function get activatedByDefault():Boolean { return true; }
		
		console static var commands:Dictionary = new Dictionary(true);
		console static var mode:String = "";

		protected var dispatcher:EventDispatcher = GlobalEventDispatcher.getInstance();
		
		
		protected var _activated:Boolean = false;
		public function get activated():Boolean 
		{
			return _activated;
		}
		
		public function activate():void
		{			
			ConsoleUtil.addSystemMessage("Plugin Activation : "+name+" ["+getQualifiedClassName(this).split("::")[1]+"]");
			_activated = true;
		}
		public function deactivate():void
		{
			ConsoleUtil.addSystemMessage("Plugin DeActivation : "+name+" ["+getQualifiedClassName(this).split("::")[1]+"]");
			_activated = false;
		}
		
		
		public function PluginBase() {}
		
		// Console command functions
		protected function registerCommand(commandName:String, callback:Function):void
		{
			console::commands[commandName] = callback;
		}
		
		protected function unregisterCommand(commandName:String):void
		{
			console::commands[commandName] = null;
			delete console::commands[commandName];
		}
		
		protected function enterConsoleMode(newMode:String):void
		{
			console::mode = newMode;
			dispatcher.dispatchEvent(new ConsoleModeEvent(ConsoleModeEvent.CHANGE, newMode));
		}
		
		protected function exitConsoleMode():void
		{
			console::mode = "";
			dispatcher.dispatchEvent(new ConsoleModeEvent(ConsoleModeEvent.CHANGE, ""));
		}
		
		// Console output functions
		protected function notice(str:String, ...replacements):void
		{
			var args:Array = replacements;
			if (!args) args = [];
			
			args.unshift('notice');
			args.unshift(str);
			formatOutput.apply(this, args);
		}
		
		protected function error(str:String, ...replacements):void
		{
			var args:Array = replacements;
			if (!args) args = [];
			
			args.unshift('error');
			args.unshift(str);
			formatOutput.apply(this, args); 
		}
		
		protected function warning(str:String, ...replacements):void
		{
			var args:Array = replacements;
			if (!args) args = [];
			
			args.unshift('warning');
			args.unshift(str);
			formatOutput.apply(this, args);
		}
		
		protected function print(str:String, ...replacements):void 
		{
			var args:Array = replacements;
			if (!args) args = [];
			
			args.unshift('weak');
			args.unshift(str);
			formatOutput.apply(this, args);
		}
		
		private function formatOutput(str:String, style:String, ...args):void
		{
			var text:String = HtmlFormatter.sprintf(str, args);
			var textLines:Array = text.split("\n");
			var lines:Vector.<TextLineModel> = Vector.<TextLineModel>([]);
			for (var i:int = 0; i < textLines.length; i++)
			{
				if (textLines[i] == "") continue;
				text = HtmlFormatter.sprintf("<%s>%s:</%s> %s", style, name, style, textLines[i]); 
				var lineModel:TextLineModel = new MarkupTextLineModel(text);
				lines.push(lineModel);
			}
			outputMsg(lines);
		}
		
		protected function clearOutput():void 
		{
			GlobalEventDispatcher.getInstance().dispatchEvent(new ConsoleOutputEvent("", true));
		}
		
		protected function outputMsg(msg:*):void 
		{
			GlobalEventDispatcher.getInstance().dispatchEvent(new ConsoleOutputEvent(msg));
			ConsoleUtil.print(msg);
		}
	}
}